package com.zhuss.order.processor;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.order.order.CreateOrderBo;
import com.zhuss.bean.bo.order.order.CreateOrderItemBo;
import com.zhuss.bean.unit.product.TrainBean;
import com.zhuss.bean.vo.order.order.CreateOrderVo;
import com.zhuss.bean.vo.product.site.DetailSiteVo;
import com.zhuss.bean.vo.product.train.DetailLineStrategyVo;
import com.zhuss.bean.vo.product.train.ListLineStrategySiteVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.common.SelectVo;
import com.zhuss.core.processor.cache.ConfigCache;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.IsEnum;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.enums.OperationStatus;
import com.zhuss.exception.DzcxException;
import com.zhuss.exception.ExceptionCode;
import com.zhuss.order.db.dao.ext.OrderDao;
import com.zhuss.order.db.entity.Order;
import com.zhuss.product.db.dao.ext.TrainDao;
import com.zhuss.product.processor.TrainRead;
import com.zhuss.product.processor.cache.LineCache;
import com.zhuss.product.processor.cache.LineStrategyCache;
import com.zhuss.product.processor.cache.SiteCache;
import com.zhuss.product.processor.cache.SiteStrategyCache;
import com.zhuss.product.processor.cache.StrategySiteCache;
import com.zhuss.util.JsonUtil;
import com.zhuss.util.NoUtil;


/**
 * @description: 订单创建
 * @author: zhushanshuo
 * @create: Mon Jan 11 16:30:32 CST 2021
 **/
@Component("orderCreate")
public class OrderCreate extends AbstractProcessor<CreateOrderVo, CreateOrderBo> implements Processor<CreateOrderVo, CreateOrderBo> {

    @Autowired
    private OrderDao orderDao;
    
    @Autowired
    private TrainDao trainDao;
    
    @Autowired
	@Qualifier("orderRead")
	private OrderRead orderRead;
    
    @Autowired
    @Qualifier("trainRead")
    private TrainRead trainRead;
    
    @Autowired
    private LineCache lineCache;
    
    @Autowired
    private SiteCache siteCache;
    
    @Autowired
    private SiteStrategyCache siteStrategyCache;
    
    @Autowired
    private LineStrategyCache lineStrategyCache;
    
    @Autowired
    private StrategySiteCache strategySiteCache;
    
    @Autowired
    private ConfigCache configCache;
    
    
    @Autowired
	@Qualifier("orderItemCreate")
	private Processor<Object, CreateOrderItemBo> orderItemCreate;
    
    
    Logger  LOGGER = LoggerFactory.getLogger(OrderCreate.class);
    
    /**
     * 校验
     */
    @Override
    public void check(CreateOrderBo bo) throws DzcxException {
    	// 创建 订单 校验， 请补充
    	Long lineStrategyId = bo.getLineStrategyId();
    	if (lineStrategyId == null || lineStrategyId <= 0) {
    		throw new DzcxException(ExceptionCode.请选择具体商品下单);
    	}
    	List<Long> trainIdList = bo.getTrainIdList();
    	if (trainIdList == null || trainIdList.isEmpty()) {
    		throw new DzcxException(ExceptionCode.请选择具体车次下单);
    	}
    	
    	List<TrainBean> trainList = trainRead.listTrainSell(lineStrategyId, trainIdList);
    	if (trainList.isEmpty() || trainList.size() != trainIdList.size()) {
    		throw new DzcxException(ExceptionCode.日期车次或库存已过期);
    	}
    	bo.setTrainList(trainList);
    	
    	Long onSiteId = bo.getOnSiteId();
    	Long offSiteId = bo.getOffSiteId();
    	Long price = bo.getPrice();
    	if (onSiteId == null || offSiteId == null) {
    		throw new DzcxException(ExceptionCode.请选择具体站点下单);
    	}
    	TrainBean train = trainList.get(0);
    	Integer rideType = train.getRideType();
    	Integer lineType = train.getLineType();
    	bo.setRideType(rideType);
    	bo.setLineType(lineType);
    	
    	if (siteStrategyCache.get(lineStrategyId, onSiteId, offSiteId, Arrays.asList(lineType)).isEmpty()) {
    		throw new DzcxException(ExceptionCode.经停站点与车次线路不符);
    	}
    	
    	List<ListLineStrategySiteVo> siteList = strategySiteCache.get(lineStrategyId);
    	Long startPrice = 0l;
    	Long endPrice = 0l;
    	for (ListLineStrategySiteVo site : siteList) {
            if (site.getSiteId().equals(onSiteId)) {
                startPrice = site.getPrice();
            }
            if (site.getSiteId().equals(offSiteId)) {
            	endPrice = site.getPrice();
                break;
            }
        }
        Long calPrice = (endPrice - startPrice) == 0l ? 100 : (endPrice - startPrice);
    	
    	if (price == null || price.longValue() <= 0) {
    		throw new DzcxException(ExceptionCode.价格不合法);
    	}
    	
    	if (price.longValue() != calPrice.longValue()) {
    		throw new DzcxException(ExceptionCode.价格已过期);
    	}
    	
    	List<TrainBean> hasBuyList = orderRead.listTrainHasBuy(trainIdList, bo.getConcurrentUserId());
    	if (hasBuyList.isEmpty()) {
    		
    	} else {
    		if (hasBuyList.retainAll(trainList)) {
    			throw new DzcxException(ExceptionCode.已买过该车次车票);
    		}
    	}
    	
    	List<SelectVo> schoolVipStopTimeList = configCache.getSchoolVipStopTime();
    	Integer minute = 30;
    	LOGGER.error("默认值： " + minute + "");
    	if (schoolVipStopTimeList != null && !schoolVipStopTimeList.isEmpty()) {
    		minute = Integer.valueOf(schoolVipStopTimeList.get(0).getName());
    	}
    	
    	LOGGER.error("更改后的值： " + minute + "");
    	
    	Date now = new Date();
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(now);
    	cal.add(Calendar.MINUTE, minute);
    	Date startTime = train.getStartTime();
    	
    	LOGGER.error(String.valueOf(cal.getTime()));
    	LOGGER.error(String.valueOf(startTime));
    	LOGGER.error(String.valueOf(cal.getTime().getTime() > startTime.getTime()));
    	if (cal.getTime().getTime() > startTime.getTime()) {
    		LOGGER.error(ExceptionCode.已过最晚购票时间.getMsg());
    		throw new DzcxException(ExceptionCode.已过最晚购票时间);
    	}
    }
    
    /**
     * 操作方法
     * @throws DzcxException 
     */
    @Override
    public CreateOrderVo process(CreateOrderBo param) throws DzcxException {
    	List<TrainBean> trainList = param.getTrainList();
    	DetailSiteVo on = siteCache.get(param.getOnSiteId());
		DetailSiteVo off = siteCache.get(param.getOffSiteId());
		DetailLineStrategyVo vo = lineStrategyCache.get(param.getLineStrategyId());
    	Order record = new Order();
    	record.setOrderNo(NoUtil.ORDER + NoUtil.genOrder());
    	record.setLineStrategyId(param.getLineStrategyId());
    	record.setLineId(vo.getLineId());
    	record.setLineName(lineCache.get(vo.getLineId()).getName());
    	record.setLineType(param.getLineType());
    	record.setRideType(param.getRideType());
    	record.setLineName(lineCache.get(vo.getLineId()).getName());
    	record.setOnSiteId(param.getOnSiteId());
    	record.setOnSiteName(on.getName());
    	record.setOffSiteId(param.getOffSiteId());
    	record.setOffSiteName(off.getName());
    	record.setStartTime(vo.getStartTime());
    	record.setPrice(param.getPrice());
    	record.setNum(param.getTrainIdList().size());
    	record.setPersonNum(param.getPersonNum());
    	record.setTotalPrice(record.getPrice() * record.getNum() * record.getPersonNum());
    	record.setStatus(param.getStatus());
    	record.setOnSiteTime(param.getOnSiteTime());
    	record.setOffSiteTime(param.getOffSiteTime());

    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	orderDao.create(record);
    	
    	Long orderId = record.getOrderId();
    	
    	for (TrainBean train : trainList) {
    		// 扣减商品库存 ，  返回受影响数量
    		Long trainId = train.getTrainId();
    		Integer personNum = record.getPersonNum();
    		Integer influnce = trainDao.used(trainId, personNum.longValue(), OperationStatus.已开通.key(), IsEnum.是.key());
    		if (influnce.equals(0)) {
    			throw new DzcxException(ExceptionCode.库存不足);
    		}
    		
    		CreateOrderItemBo itemBo = new CreateOrderItemBo();
    		itemBo.setDate(train.getDate());
    		BeanUtils.copyProperties(param, itemBo);
    		BeanUtils.copyProperties(record, itemBo);
    		itemBo.setTrainId(trainId);
    		itemBo.setCreateTime(record.getCreateTime());
    		itemBo.setOrderId(orderId);
    		itemBo.setStartTime(record.getStartTime());
    		itemBo.setPersonNum(record.getPersonNum());
    		itemBo.setPrice(record.getPrice() * itemBo.getPersonNum());
    		orderItemCreate.process(itemBo);
    	}
    	
    	param.setTargetId(orderId);
    	CreateOrderVo result = new CreateOrderVo();
    	result.setOrderId(orderId);
        return result;
    }
    
    /**
     * 操作日志
     */
	@Override
	public CreateOrderVo log(CreateOrderBo param) throws DzcxException {
		OpLog record = new OpLog();
		record.setMoudle(MoudleEnum.订单.key());
		record.setAction(LogActionEnum.订单创建.key());
    	record.setTargetId(param.getTargetId());
    	record.setTargetName(param.getOrderNo());
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
